#include "freertos/FreeRTOS.h"
#include "freertos/task.h"                                                                          
#include "esp_log.h"
#include "Drivers/uart_drv.h"
#include "App/uart_console.h"
#include "App/sn_handle.h"
#include "Drivers/nvs_drv.h"
#include "tools.h"
#include <string.h>
#include "Drivers/smartconfig_wifi.h"
#include "Drivers/wifi_drv.h"
#include "Drivers/spiffs_drv.h"

#define TAG   "uart_console"

static void SnWriteHandler(const uint8_t *sourse, uint32_t len);

/**
 * @brief 串口控制台接收任务函数
 *
 * 该任务负责处理串口控制台的接收数据,包括以下功能:
 * - SN码的写入和清除
 * - WiFi配网控制
 * - WiFi配置清除
 * - SPIFFS文件系统格式化
 * - 串口数据转发
 *
 * @param param 任务参数(未使用)
 * @return void
 *
 * @note 该任务会持续运行,循环接收串口数据并根据接收内容执行相应操作
 */
void UartConsoleRecvTask(void *param)
{
    ESP_LOGI(TAG, "uart_console_recv_task start");
    uint8_t data[UART_CONSOLE_BUF_SIZE] = {0};
    uint32_t len = 0;
    // bool SnExist = false;                         //获取SN状态

    uart_driver_install(UART_CONSOLE_NUM, UART_CONSOLE_BUF_SIZE, 0, 0, NULL, 0);          //注册串口

    while(1)
    {
        len = uart_read_bytes(UART_CONSOLE_NUM, data, UART_CONSOLE_BUF_SIZE, 20 / portTICK_PERIOD_MS);
        
        if(!len) continue;
        
        if(strnstr((char*)data, SN_ACK, sizeof(SN_ACK)) && !GetSNStatus())            //收到SN
        {   
            xEventGroupClearBits(SnEventGroup, SN_REQUEST_BIT);                 //清除询问SN
            SnWriteHandler(data, len);                                          //烧录SN
        }

        if(strnstr((char*)data, SN_CLEAR, sizeof(SN_CLEAR)))                    //清除SN
        {
            if(ESP_OK == erase_nvs_space(NVS_SN_NAMESPACE, NVS_SN_KEY))
                esp_restart();
        }    

        if(strnstr((char*)data, SC_WIFI_START, sizeof(SC_WIFI_START)))          //配网        
        {
            SmartConfigStart();
        }    

        if(strnstr((char*)data, WIFI_CLEAR, sizeof(WIFI_CLEAR)))                //清除wifi
        {
            if(ESP_OK == erase_nvs_space(NVS_WIFI_NAMESPACE, NVS_WIFI_SSID_KEY))
                esp_restart();
        } 

        if(strnstr((char*)data, SPIFFS_CLEAR, sizeof(SPIFFS_CLEAR)))            //格式化SPIFFS    
        {
            esp_spiffs_format(NULL);
        } 
        if(strnstr((char*)data, UART_DATA_TRANS, sizeof(UART_DATA_TRANS)))      //数据转发 
        {
            uart_write_bytes(UART_DATA_NUM, data + 3, len - 3);
        } 
        // vTaskDelay(10 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

/**
 * @brief 烧录SN函数
 * 
 * @param sourse  上位机发送来的SN
 * @param s_len   数据长度   
 * @return void
 * 
 * @note 烧录sn通信协议与烧录软件同步，请勿轻易更改，否则烧录软件也需要更改
 */
static void SnWriteHandler(const uint8_t *sourse, uint32_t s_len)
{
    uint32_t len = 0;                           //接收长度
    uint8_t buffer[20] = {0};                   //接收数组
    uint8_t SendBuffer[20];                     //发送数组
    uint8_t SN_Hex[SN_LEN];                     //收到的SN转Hex
    uint8_t SN_Str[SN_LEN * 2];                 //SN字符串
    uint8_t *MacStr = GetMACStr();              //获取Mac地址
    uint8_t MacCmp[MAC_CMP_LEN] = MAC_RSP_OK;   //用于确认上位机收到的Mac地址正确

    if (s_len != 16)          // 长度错误
    {
        uart_write_bytes(UART_CONSOLE_NUM, SN_LEN_ERR, sizeof(SN_LEN_ERR));
        xEventGroupSetBits(SnEventGroup, SN_REQUEST_BIT);
        return;
    }
    int check = SN_CheckSum((uint8_t *)sourse, s_len - CHECK_SUM_LEN);


    if (check != sourse[s_len - CHECK_SUM_LEN])  // checksum错误
    {

        uart_write_bytes(UART_CONSOLE_NUM, SN_CHECK_ERR, sizeof(SN_LEN_ERR));
        xEventGroupSetBits(SnEventGroup, SN_REQUEST_BIT);
        return;
    }

    sn_to_hex((char *)sourse + 3, (char*)SN_Hex + 1);   //预留第一个位置放crc
                                                        // "010A" -> 01 0a   字符串转16进制
    SN_Hex[0] = calc_crc8(SN_Hex + 1, 6);               //计算crc

    for (uint8_t i = 0; i < SN_LEN - 1; i++)            // sn最后一个字节未使用-1，不转ascii
    {
        sprintf((char*)SN_Str + i * 2, "%02X", SN_Hex[i]);
    }

    strcpy((char*)SendBuffer, SN_OK);
    strcpy((char*)SendBuffer + strlen(SN_OK), (char*)SN_Str);      

    uart_write_bytes(UART_CONSOLE_NUM, SendBuffer, strlen((char*)SendBuffer)); //响应获取到格式正确的SN

    memset(SendBuffer, 0, strlen((char*)SendBuffer));

    strcat((char*)MacCmp + strlen((char*)MacCmp), (char*)MacStr);              //用于后面比较mac地址

    while (1)
    {
        len = uart_read_bytes(UART_CONSOLE_NUM, buffer, 20, 20 / portTICK_PERIOD_MS);
        if(!len) continue;

        if(strnstr((char*)buffer, MAC_REQ, sizeof(MAC_REQ)))                    //收到获取mac请求
        {
 
            strcpy((char*)SendBuffer, MAC_RSP);
            strcpy((char*)SendBuffer + strlen(MAC_RSP), (char*)MacStr);

            SendBuffer[strlen((char*)SendBuffer)] = SN_CheckSum(MacStr, strlen((char*)MacStr));
            uart_write_bytes(UART_CONSOLE_NUM, SendBuffer, strlen((char*)SendBuffer));
        }
        
        if(strnstr((char*)buffer, MAC_RSP_OK, sizeof(MAC_RSP_OK)))              //上位机成功获取到mac地址
        {
            if (memcmp(MacCmp, buffer, MAC_CMP_LEN) == 0)                       //对比上位机获取到的MAC地址是否正确
            {   
                if (write_nvs_space(NVS_SN_NAMESPACE, NVS_SN_KEY, (char*)SN_Str) != ESP_OK)
                    esp_restart();                                              //失败自动重启
                else
                    uart_write_bytes(UART_CONSOLE_NUM, SN_WRITE_FINISH, strlen(SN_WRITE_FINISH));       //发送成功标志字符串

                return;
            }
            else  
            {
                uart_write_bytes(UART_CONSOLE_NUM, "MAC ERROE", strlen("MAC ERROE"));
                xEventGroupSetBits(SnEventGroup, SN_REQUEST_BIT);
            }

        }

        // vTaskDelay(10 / portTICK_PERIOD_MS);
    }
    
}